/*
 * Robot.java
 * Copyright (C) 2010 Lhrod
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 */
package Robot;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.Point;
import java.awt.event.InputEvent;
import java.util.HashMap;

/*
 * Robot.java
 *
 * Created on 9 de marzo de 2010, 9:18
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
public class Robot {

    boolean windowsSystem;
    boolean actWin = false;
    boolean nativeMode = false;
    boolean nativeSystem;
    private NativeLibrary nativeL;
    private java.awt.Robot robot;

    public Robot() throws AWTException {
        robot = new java.awt.Robot();
        init();
    }

    public Robot(GraphicsDevice gd) throws AWTException {
        robot = new java.awt.Robot(gd);
        init();
    }

    private void init() {
        windowsSystem = System.getProperty("os.name").toLowerCase().startsWith("windows");
        nativeSystem = windowsSystem;

        if (windowsSystem) {
            nativeL = new WinNative();
        }
    }

    public HashMap getAllVisibleWindow() {
        if (nativeSystem) {
            return nativeL.getAllVisibleWindow();
        }
        return new HashMap();
    }

    public boolean isActWin() {
        return actWin;
    }

    public boolean isNativeSystem() {
        return nativeSystem;
    }

    public boolean isNativeMode() {
        return nativeMode;
    }

    public void setAutoDelay(int i) {
        robot.setAutoDelay(i);
    }

    public int getAutoDelay() {
        return robot.getAutoDelay();
    }

    public void text(String strTmp) {
        if (actWin && nativeMode) {
            nativeL.text(strTmp);
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(1);
            for (char b : strTmp.toUpperCase().toCharArray()) {
                robot.keyPress(b);
                robot.keyRelease(b);
            }
            robot.setAutoDelay(retr);
        }
    }

    public void keyRelease(int keyCode) {
        System.out.println((char)keyCode);
        if (actWin && nativeMode) {
            nativeL.keyRelease(keyCode);
            delay(robot.getAutoDelay());
        } else {
            robot.keyRelease(keyCode);
        }
    }

    public void keyPress(int keyCode) {
        System.out.println((char)keyCode);
        if (actWin && nativeMode) {
            nativeL.keyPress(keyCode);
            delay(robot.getAutoDelay());
        } else {
            robot.keyPress(keyCode);
        }
    }

    public void key(int i) {
        System.out.println((char)i);
        if (actWin && nativeMode) {
            nativeL.key((byte) i);
            delay(robot.getAutoDelay());
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(1);
            robot.keyPress(i);
            robot.keyRelease(i);
            robot.setAutoDelay(retr);
        }
    }

    public void mouseMove(int x, int y) {
        if (actWin && nativeMode) {
            nativeL.mouseMove(x, y);
            delay(robot.getAutoDelay());
        } else {
            robot.mouseMove(x, y);
        }
    }

    public void mousePress(int x, int y, int button) {
        if (actWin && nativeMode) {
            nativeL.mousePress(x, y, button);
            delay(robot.getAutoDelay());
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(0);
            robot.mouseMove(x, y);
            robot.mousePress(button);
            robot.setAutoDelay(retr);
        }
    }

    public void mouseRelease(int x, int y, int button) {
        if (actWin && nativeMode) {
            nativeL.mouseRelease(x, y, button);
            delay(robot.getAutoDelay());
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(0);
            robot.mouseMove(x, y);
            robot.mouseRelease(button);
            robot.setAutoDelay(retr);
        }
    }

    public void mouseClick(int x, int y, int button) {
        if (actWin && nativeMode) {
            nativeL.mouseClick(x, y, button);
            delay(robot.getAutoDelay());
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(0);
            robot.mouseMove(x, y);
            robot.mousePress(button);
            robot.mouseRelease(button);
            robot.setAutoDelay(retr);
        }
    }

    public void mouseDClick(int x, int y, int button) {
        if (actWin && nativeMode) {
            nativeL.mouseDClick(x, y, button);
            delay(robot.getAutoDelay());
        } else {
            int retr = robot.getAutoDelay();
            robot.setAutoDelay(0);
            robot.mouseMove(x, y);
            robot.mousePress(button);
            robot.delay(retr);
            robot.mouseRelease(button);
            robot.delay(retr);
            robot.mousePress(button);
            robot.delay(retr);
            robot.mouseRelease(button);
            robot.setAutoDelay(retr);
        }
    }

    public Color getPixelColor(int x, int y) {
        Color color = null;
        if (actWin && nativeMode) {
            color = nativeL.getPixelColor(x, y);
        } else {
            color = robot.getPixelColor(x, y);
        }
        return color;
    }

    public void setActNativeHandle(Object hWnd) {
        nativeL.setActNativeHandle(hWnd);
        this.actWin = true;
        this.nativeMode = true;
    }

    public void setNativeMode(boolean value) {
        nativeMode = value;
    }

    public void delay(long d) {
        try {
            Thread.sleep(d);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isKeyPress(byte k) {
        return nativeL.isKeyPress(k);
    }

    public boolean isMouseButtonPress(int button) {
        return nativeL.isMouseButtonPress(button);
    }

    public Point getMousePos() {
        int[] coor = nativeL.getMousePos();
        return new Point(coor[0], coor[1]);
    }
}

interface NativeLibrary {

    public void text(String txt);

    public void key(byte k);

    public void keyPress(int keyCode);

    public void keyRelease(int keyCode);

    public void mouseMove(int x, int y);

    public void mousePress(int x, int y, int bmask);

    public void mouseRelease(int x, int y, int bmask);

    public void mouseClick(int x, int y, int button);

    public void mouseDClick(int x, int y, int button);

    public HashMap getAllVisibleWindow();

    public void setActNativeHandle(Object handle);

    public Color getPixelColor(int x, int y);

    public boolean isMouseButtonPress(int button);

    public boolean isKeyPress(byte k);

    public int[] getMousePos();
}

class WinNative implements NativeLibrary {

    private User32 user32 = User32.INSTANCE;
    private Gdi32 gdi32 = Gdi32.INSTANCE;
    private Pointer hWnd;
    private Pointer hdc;
    public static final int MASK_ISPULSE = (~(byte) 0) - (byte) 1;
    public static final int YNUMBITS = 16;

    public void text(String txt) {
        for (byte b : txt.getBytes()) {
            user32.SendMessageA(hWnd, User32.WM_CHAR, b, null);
            //user32.PostMessageA(hWnd, User32.WM_CHAR, b, null);
        }
    }

    public void key(byte k) {
        user32.SendMessageA(hWnd, User32.WM_CHAR, k, null);
        //user32.PostMessageA(hWnd, User32.WM_CHAR, k, null);
    }

    public void keyPress(int keyCode) {
        //user32.SendMessageA(hWnd, User32.WM_KEYDOWN, keyCode, null);
        user32.PostMessageA(hWnd, User32.WM_KEYDOWN, keyCode, null);
    }

    public void keyRelease(int keyCode) {
        //user32.SendMessageA(hWnd, User32.WM_KEYUP, keyCode, null);
        user32.PostMessageA(hWnd, User32.WM_KEYUP, keyCode, null);
    }

    public void mouseMove(int x, int y) {
        user32.SendMessageA(hWnd, User32.WM_MOUSEMOVE, 0, x + (y << YNUMBITS));
    }

    public void mousePress(int x, int y, int button) {
        switch (button) {
            case InputEvent.BUTTON1_MASK:
                button = User32.WM_LBUTTONDOWN;
                break;
            case InputEvent.BUTTON3_MASK:
                button = User32.WM_RBUTTONDOWN;
                break;
            case InputEvent.BUTTON2_MASK:
                button = User32.WM_MBUTTONDOWN;
                break;
        }
        user32.SendMessageA(hWnd, button, 0, x + (y << YNUMBITS));
    }

    public void mouseRelease(int x, int y, int button) {
        switch (button) {
            case InputEvent.BUTTON1_MASK:
                button = User32.WM_LBUTTONUP;
                break;
            case InputEvent.BUTTON3_MASK:
                button = User32.WM_RBUTTONUP;
                break;
            case InputEvent.BUTTON2_MASK:
                button = User32.WM_MBUTTONUP;
                break;
        }
        user32.SendMessageA(hWnd, button, 0, x + (y << YNUMBITS));
    }

    public void mouseClick(int x, int y, int button) {
        x += (y << YNUMBITS);
        switch (button) {
            case InputEvent.BUTTON1_MASK:
                button = User32.WM_LBUTTONDOWN;
                y = User32.WM_LBUTTONUP;
                break;
            case InputEvent.BUTTON3_MASK:
                button = User32.WM_RBUTTONDOWN;
                y = User32.WM_RBUTTONUP;
                break;
            case InputEvent.BUTTON2_MASK:
                button = User32.WM_MBUTTONDOWN;
                y = User32.WM_MBUTTONUP;
                break;
        }
        user32.SendMessageA(hWnd, button, 0, x);
        user32.SendMessageA(hWnd, y, 0, x);
    }

    public void mouseDClick(int x, int y, int button) {
        switch (button) {
            case InputEvent.BUTTON1_MASK:
                button = User32.WM_LBUTTONDBLCLK;
                break;
            case InputEvent.BUTTON3_MASK:
                button = User32.WM_RBUTTONDBLCLK;
                break;
            case InputEvent.BUTTON2_MASK:
                button = User32.WM_MBUTTONDBLCLK;
                break;
        }
        user32.SendMessageA(hWnd, button, 0, x + (y << YNUMBITS));
    }

    public HashMap getAllVisibleWindow() {
        final HashMap wndMap = new HashMap();
        WNDENUMPROC proc = new WNDENUMPROC() {

            public boolean callback(Pointer hWnd, Pointer data) {
                if (user32.IsWindowVisible(hWnd)) {
                    byte[] buffer = new byte[256];
                    int res = user32.GetWindowTextA(hWnd, buffer, buffer.length);
                    wndMap.put(hWnd, Native.toString(buffer));
                }
                return true;
            }
        };
        boolean EnumWindows = user32.EnumWindows(proc, null);
        return wndMap;
    }

    public void setActNativeHandle(Object handle) {
        hWnd = (Pointer) handle;
        hdc = user32.GetWindowDC(hWnd);
    }

    public Color getPixelColor(int x, int y) {
        int[] cComp = gdi32.GetPixel(hdc, x, y);
        return new Color(cComp[0], cComp[1], cComp[3]);
    }

    public boolean isMouseButtonPress(int button) {
        switch (InputEvent.BUTTON1_MASK) {
            case InputEvent.BUTTON1_MASK:
                button = User32.VK_LBUTTON;
                break;
            case InputEvent.BUTTON3_MASK:
                button = User32.VK_RBUTTON;
                break;
            case InputEvent.BUTTON2_MASK:
                button = User32.VK_MBUTTON;
                break;
        }
        return (user32.GetAsyncKeyState(button) & MASK_ISPULSE) != 0;
    }

    public boolean isKeyPress(byte k) {
        return (user32.GetAsyncKeyState(k) & MASK_ISPULSE) != 0;
    }

    public int[] getMousePos() {
        int[] coor = new int[2];
        user32.GetCursorPos(coor);
        return coor;
    }
}

interface WNDENUMPROC extends StdCallCallback {

    boolean callback(Pointer hWnd, Pointer arg);
}

interface Gdi32 extends StdCallLibrary {

    Gdi32 INSTANCE = (Gdi32) Native.loadLibrary("gdi32", Gdi32.class);

    int[] GetPixel(Pointer hdc, int nXPos, int nYPos);
}

interface User32 extends StdCallLibrary {

    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);

    int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);

    Pointer GetWindowDC(Pointer hWnd);

    Pointer WindowFromPoint(int xPoint, int yPoint);

    boolean GetCursorPos(int[] coor);

    int GetAsyncKeyState(int vKey);

    boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);

    boolean IsWindow(Pointer hWnd);

    boolean IsWindowVisible(Pointer hWnd);

    //public void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
    public short VkKeyScanA(byte c);

    public int PostMessageA(Pointer hwnd, int wMsg, int wParam, String lParam);

    public int SendMessageA(Pointer hwnd, int wMsg, int wParam, String lParam);

    public int SendMessageA(Pointer hwnd, int wMsg, int wParam, int lParam);
    public static final int VK_LBUTTON = 0x01, VK_RBUTTON = 0x02, VK_MBUTTON = 0x04;
    public static final int WM_NULL = 0x00;
    public static final int WM_CREATE = 0x01;
    public static final int WM_DESTROY = 0x02;
    public static final int WM_MOVE = 0x03;
    public static final int WM_SIZE = 0x05;
    public static final int WM_ACTIVATE = 0x06;
    public static final int WM_SETFOCUS = 0x07;
    public static final int WM_KILLFOCUS = 0x08;
    public static final int WM_ENABLE = 0x0A;
    public static final int WM_SETREDRAW = 0x0B;
    public static final int WM_SETTEXT = 0x0C;
    public static final int WM_GETTEXT = 0x0D;
    public static final int WM_GETTEXTLENGTH = 0x0E;
    public static final int WM_PAINT = 0x0F;
    public static final int WM_CLOSE = 0x10;
    public static final int WM_QUERYENDSESSION = 0x11;
    public static final int WM_QUIT = 0x12;
    public static final int WM_QUERYOPEN = 0x13;
    public static final int WM_ERASEBKGND = 0x14;
    public static final int WM_SYSCOLORCHANGE = 0x15;
    public static final int WM_ENDSESSION = 0x16;
    public static final int WM_SYSTEMERROR = 0x17;
    public static final int WM_SHOWWINDOW = 0x18;
    public static final int WM_CTLCOLOR = 0x19;
    public static final int WM_WININICHANGE = 0x1A;
    public static final int WM_SETTINGCHANGE = 0x1A;
    public static final int WM_DEVMODECHANGE = 0x1B;
    public static final int WM_ACTIVATEAPP = 0x1C;
    public static final int WM_FONTCHANGE = 0x1D;
    public static final int WM_TIMECHANGE = 0x1E;
    public static final int WM_CANCELMODE = 0x1F;
    public static final int WM_SETCURSOR = 0x20;
    public static final int WM_MOUSEACTIVATE = 0x21;
    public static final int WM_CHILDACTIVATE = 0x22;
    public static final int WM_QUEUESYNC = 0x23;
    public static final int WM_GETMINMAXINFO = 0x24;
    public static final int WM_PAINTICON = 0x26;
    public static final int WM_ICONERASEBKGND = 0x27;
    public static final int WM_NEXTDLGCTL = 0x28;
    public static final int WM_SPOOLERSTATUS = 0x2A;
    public static final int WM_DRAWITEM = 0x2B;
    public static final int WM_MEASUREITEM = 0x2C;
    public static final int WM_DELETEITEM = 0x2D;
    public static final int WM_VKEYTOITEM = 0x2E;
    public static final int WM_CHARTOITEM = 0x2F;
    public static final int WM_SETFONT = 0x30;
    public static final int WM_GETFONT = 0x31;
    public static final int WM_SETHOTKEY = 0x32;
    public static final int WM_GETHOTKEY = 0x33;
    public static final int WM_QUERYDRAGICON = 0x37;
    public static final int WM_COMPAREITEM = 0x39;
    public static final int WM_COMPACTING = 0x41;
    public static final int WM_WINDOWPOSCHANGING = 0x46;
    public static final int WM_WINDOWPOSCHANGED = 0x47;
    public static final int WM_POWER = 0x48;
    public static final int WM_COPYDATA = 0x4A;
    public static final int WM_CANCELJOURNAL = 0x4B;
    public static final int WM_NOTIFY = 0x4E;
    public static final int WM_INPUTLANGCHANGEREQUEST = 0x50;
    public static final int WM_INPUTLANGCHANGE = 0x51;
    public static final int WM_TCARD = 0x52;
    public static final int WM_HELP = 0x53;
    public static final int WM_USERCHANGED = 0x54;
    public static final int WM_NOTIFYFORMAT = 0x55;
    public static final int WM_CONTEXTMENU = 0x7B;
    public static final int WM_STYLECHANGING = 0x7C;
    public static final int WM_STYLECHANGED = 0x7D;
    public static final int WM_DISPLAYCHANGE = 0x7E;
    public static final int WM_GETICON = 0x7F;
    public static final int WM_SETICON = 0x80;
    public static final int WM_NCCREATE = 0x81;
    public static final int WM_NCDESTROY = 0x82;
    public static final int WM_NCCALCSIZE = 0x83;
    public static final int WM_NCHITTEST = 0x84;
    public static final int WM_NCPAINT = 0x85;
    public static final int WM_NCACTIVATE = 0x86;
    public static final int WM_GETDLGCODE = 0x87;
    public static final int WM_NCMOUSEMOVE = 0xA0;
    public static final int WM_NCLBUTTONDOWN = 0xA1;
    public static final int WM_NCLBUTTONUP = 0xA2;
    public static final int WM_NCLBUTTONDBLCLK = 0xA3;
    public static final int WM_NCRBUTTONDOWN = 0xA4;
    public static final int WM_NCRBUTTONUP = 0xA5;
    public static final int WM_NCRBUTTONDBLCLK = 0xA6;
    public static final int WM_NCMBUTTONDOWN = 0xA7;
    public static final int WM_NCMBUTTONUP = 0xA8;
    public static final int WM_NCMBUTTONDBLCLK = 0xA9;
    public static final int WM_KEYFIRST = 0x100;
    public static final int WM_KEYDOWN = 0x100;
    public static final int WM_KEYUP = 0x101;
    public static final int WM_CHAR = 0x102;
    public static final int WM_DEADCHAR = 0x103;
    public static final int WM_SYSKEYDOWN = 0x104;
    public static final int WM_SYSKEYUP = 0x105;
    public static final int WM_SYSCHAR = 0x106;
    public static final int WM_SYSDEADCHAR = 0x107;
    public static final int WM_KEYLAST = 0x108;
    public static final int WM_IME_STARTCOMPOSITION = 0x10D;
    public static final int WM_IME_ENDCOMPOSITION = 0x10E;
    public static final int WM_IME_COMPOSITION = 0x10F;
    public static final int WM_IME_KEYLAST = 0x10F;
    public static final int WM_INITDIALOG = 0x110;
    public static final int WM_COMMAND = 0x111;
    public static final int WM_SYSCOMMAND = 0x112;
    public static final int WM_TIMER = 0x113;
    public static final int WM_HSCROLL = 0x114;
    public static final int WM_VSCROLL = 0x115;
    public static final int WM_INITMENU = 0x116;
    public static final int WM_INITMENUPOPUP = 0x117;
    public static final int WM_MENUSELECT = 0x11F;
    public static final int WM_MENUCHAR = 0x120;
    public static final int WM_ENTERIDLE = 0x121;
    public static final int WM_CTLCOLORMSGBOX = 0x132;
    public static final int WM_CTLCOLOREDIT = 0x133;
    public static final int WM_CTLCOLORLISTBOX = 0x134;
    public static final int WM_CTLCOLORBTN = 0x135;
    public static final int WM_CTLCOLORDLG = 0x136;
    public static final int WM_CTLCOLORSCROLLBAR = 0x137;
    public static final int WM_CTLCOLORSTATIC = 0x138;
    public static final int WM_MOUSEFIRST = 0x200;
    public static final int WM_MOUSEMOVE = 0x200;
    public static final int WM_LBUTTONDOWN = 0x201;
    public static final int WM_LBUTTONUP = 0x202;
    public static final int WM_LBUTTONDBLCLK = 0x203;
    public static final int WM_RBUTTONDOWN = 0x204;
    public static final int WM_RBUTTONUP = 0x205;
    public static final int WM_RBUTTONDBLCLK = 0x206;
    public static final int WM_MBUTTONDOWN = 0x207;
    public static final int WM_MBUTTONUP = 0x208;
    public static final int WM_MBUTTONDBLCLK = 0x209;
    public static final int WM_MOUSEWHEEL = 0x20A;
    public static final int WM_MOUSEHWHEEL = 0x20E;
    public static final int WM_PARENTNOTIFY = 0x210;
    public static final int WM_ENTERMENULOOP = 0x211;
    public static final int WM_EXITMENULOOP = 0x212;
    public static final int WM_NEXTMENU = 0x213;
    public static final int WM_SIZING = 0x214;
    public static final int WM_CAPTURECHANGED = 0x215;
    public static final int WM_MOVING = 0x216;
    public static final int WM_POWERBROADCAST = 0x218;
    public static final int WM_DEVICECHANGE = 0x219;
    public static final int WM_MDICREATE = 0x220;
    public static final int WM_MDIDESTROY = 0x221;
    public static final int WM_MDIACTIVATE = 0x222;
    public static final int WM_MDIRESTORE = 0x223;
    public static final int WM_MDINEXT = 0x224;
    public static final int WM_MDIMAXIMIZE = 0x225;
    public static final int WM_MDITILE = 0x226;
    public static final int WM_MDICASCADE = 0x227;
    public static final int WM_MDIICONARRANGE = 0x228;
    public static final int WM_MDIGETACTIVE = 0x229;
    public static final int WM_MDISETMENU = 0x230;
    public static final int WM_ENTERSIZEMOVE = 0x231;
    public static final int WM_EXITSIZEMOVE = 0x232;
    public static final int WM_DROPFILES = 0x233;
    public static final int WM_MDIREFRESHMENU = 0x234;
    public static final int WM_IME_SETCONTEXT = 0x281;
    public static final int WM_IME_NOTIFY = 0x282;
    public static final int WM_IME_CONTROL = 0x283;
    public static final int WM_IME_COMPOSITIONFULL = 0x284;
    public static final int WM_IME_SELECT = 0x285;
    public static final int WM_IME_CHAR = 0x286;
    public static final int WM_IME_KEYDOWN = 0x290;
    public static final int WM_IME_KEYUP = 0x291;
    public static final int WM_MOUSEHOVER = 0x2A1;
    public static final int WM_NCMOUSELEAVE = 0x2A2;
    public static final int WM_MOUSELEAVE = 0x2A3;
    public static final int WM_CUT = 0x300;
    public static final int WM_COPY = 0x301;
    public static final int WM_PASTE = 0x302;
    public static final int WM_CLEAR = 0x303;
    public static final int WM_UNDO = 0x304;
    public static final int WM_RENDERFORMAT = 0x305;
    public static final int WM_RENDERALLFORMATS = 0x306;
    public static final int WM_DESTROYCLIPBOARD = 0x307;
    public static final int WM_DRAWCLIPBOARD = 0x308;
    public static final int WM_PAINTCLIPBOARD = 0x309;
    public static final int WM_VSCROLLCLIPBOARD = 0x30A;
    public static final int WM_SIZECLIPBOARD = 0x30B;
    public static final int WM_ASKCBFORMATNAME = 0x30C;
    public static final int WM_CHANGECBCHAIN = 0x30D;
    public static final int WM_HSCROLLCLIPBOARD = 0x30E;
    public static final int WM_QUERYNEWPALETTE = 0x30F;
    public static final int WM_PALETTEISCHANGING = 0x310;
    public static final int WM_PALETTECHANGED = 0x311;
    public static final int WM_HOTKEY = 0x312;
    public static final int WM_PRINT = 0x317;
    public static final int WM_PRINTCLIENT = 0x318;
    public static final int WM_HANDHELDFIRST = 0x358;
    public static final int WM_HANDHELDLAST = 0x35F;
    public static final int WM_PENWINFIRST = 0x380;
    public static final int WM_PENWINLAST = 0x38F;
    public static final int WM_COALESCE_FIRST = 0x390;
    public static final int WM_COALESCE_LAST = 0x39F;
    public static final int WM_DDE_FIRST = 0x3E0;
    public static final int WM_DDE_INITIATE = 0x3E0;
    public static final int WM_DDE_TERMINATE = 0x3E1;
    public static final int WM_DDE_ADVISE = 0x3E2;
    public static final int WM_DDE_UNADVISE = 0x3E3;
    public static final int WM_DDE_ACK = 0x3E4;
    public static final int WM_DDE_DATA = 0x3E5;
    public static final int WM_DDE_REQUEST = 0x3E6;
    public static final int WM_DDE_POKE = 0x3E7;
    public static final int WM_DDE_EXECUTE = 0x3E8;
    public static final int WM_DDE_LAST = 0x3E8;
    public static final int WM_USER = 0x400;
    public static final int WM_APP = 0x8000;
}
